]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
Support -st-shadow for all background properties
authorFlorian Müllner <fmuellner@src.gnome.org>
Thu, 11 Mar 2010 23:14:12 +0000 (00:14 +0100)
committerFlorian Müllner <fmuellner@src.gnome.org>
Mon, 10 May 2010 18:17:20 +0000 (20:17 +0200)
Extend the existing support for -st-shadow to apply to the background,
background-gradient and border properties in addition to background-image.

https://bugzilla.gnome.org/show_bug.cgi?id=613832

src/st/st-theme-node-drawing.c
src/st/st-theme-node-private.h

index d202a837113141e5283c058477939d9b46b5ccf8..ec226de594a6c28dc24d917d78f5e18391e3009c 100644 (file)
@@ -681,10 +681,12 @@ _st_theme_node_free_drawing_state (StThemeNode  *node)
 {
   if (node->background_texture != COGL_INVALID_HANDLE)
     cogl_handle_unref (node->background_texture);
-  if (node->shadow_material != COGL_INVALID_HANDLE)
-    cogl_handle_unref (node->shadow_material);
+  if (node->background_shadow_material != COGL_INVALID_HANDLE)
+    cogl_handle_unref (node->background_shadow_material);
   if (node->border_texture != COGL_INVALID_HANDLE)
     cogl_handle_unref (node->border_texture);
+  if (node->border_shadow_material != COGL_INVALID_HANDLE)
+    cogl_handle_unref (node->border_shadow_material);
 
   _st_theme_node_init_drawing_state (node);
 }
@@ -693,10 +695,15 @@ void
 _st_theme_node_init_drawing_state (StThemeNode *node)
 {
   node->background_texture = COGL_INVALID_HANDLE;
-  node->shadow_material = COGL_INVALID_HANDLE;
+  node->background_shadow_material = COGL_INVALID_HANDLE;
+  node->border_shadow_material = COGL_INVALID_HANDLE;
   node->border_texture = COGL_INVALID_HANDLE;
 }
 
+static void st_theme_node_paint_borders (StThemeNode           *node,
+                                         const ClutterActorBox *box,
+                                         guint8                 paint_opacity);
+
 static void
 st_theme_node_render_resources (StThemeNode   *node,
                                 float          width,
@@ -704,6 +711,7 @@ st_theme_node_render_resources (StThemeNode   *node,
 {
   StTextureCache *texture_cache;
   StBorderImage *border_image;
+  StShadow *shadow_spec;
   const char *background_image;
 
   texture_cache = st_texture_cache_get_default ();
@@ -720,6 +728,8 @@ st_theme_node_render_resources (StThemeNode   *node,
   _st_theme_node_ensure_background (node);
   _st_theme_node_ensure_geometry (node);
 
+  shadow_spec = st_theme_node_get_shadow (node);
+
   /* Load referenced images from disk and draw anything we need with cairo now */
 
   border_image = st_theme_node_get_border_image (node);
@@ -736,17 +746,50 @@ st_theme_node_render_resources (StThemeNode   *node,
       node->border_texture = st_theme_node_render_gradient (node);
     }
 
+  if (shadow_spec)
+    {
+      if (node->border_texture != COGL_INVALID_HANDLE)
+        node->border_shadow_material = create_shadow_material (node, node->border_texture);
+      else if (node->background_color.alpha > 0 ||
+               node->border_width[ST_SIDE_TOP] > 0 ||
+               node->border_width[ST_SIDE_LEFT] > 0 ||
+               node->border_width[ST_SIDE_RIGHT] > 0 ||
+               node->border_width[ST_SIDE_BOTTOM] > 0)
+        {
+          CoglHandle buffer, offscreen;
+
+          buffer = cogl_texture_new_with_size (width,
+                                               height,
+                                               COGL_TEXTURE_NO_SLICING,
+                                               COGL_PIXEL_FORMAT_ANY);
+          offscreen = cogl_offscreen_new_to_texture (buffer);
+
+          if (offscreen != COGL_INVALID_HANDLE)
+            {
+              ClutterActorBox box = { 0, 0, width, height };
+
+              cogl_push_framebuffer (offscreen);
+              cogl_ortho (0, width, height, 0, 0, 1.0);
+              st_theme_node_paint_borders (node, &box, 0xFF);
+              cogl_pop_framebuffer ();
+              cogl_handle_unref (offscreen);
+
+              node->border_shadow_material = create_shadow_material (node,
+                                                                     buffer);
+            }
+          cogl_handle_unref (buffer);
+        }
+    }
+
   background_image = st_theme_node_get_background_image (node);
   if (background_image != NULL)
     {
-      StShadow *shadow_spec;
 
       node->background_texture = st_texture_cache_load_file_to_cogl_texture (texture_cache, background_image);
 
-      shadow_spec = st_theme_node_get_shadow (node);
       if (shadow_spec)
         {
-          node->shadow_material = create_shadow_material (node, node->background_texture);
+          node->background_shadow_material = create_shadow_material (node, node->background_texture);
         }
     }
 
@@ -1043,6 +1086,30 @@ st_theme_node_paint (StThemeNode           *node,
    * border_image and a single background image above it.
    */
 
+  if (node->border_shadow_material)
+    {
+      StShadow *shadow_spec;
+      ClutterActorBox shadow_box;
+
+      shadow_spec = node->shadow;
+
+      shadow_box.x1 = allocation.x1 + shadow_spec->xoffset
+                      - shadow_spec->blur - shadow_spec->spread;
+      shadow_box.y1 = allocation.y1 + shadow_spec->yoffset
+                      - shadow_spec->blur - shadow_spec->spread;
+      shadow_box.x2 = allocation.x2 + shadow_spec->xoffset
+                      + shadow_spec->blur + shadow_spec->spread;
+      shadow_box.y2 = allocation.y2 + shadow_spec->yoffset
+                      + shadow_spec->blur + shadow_spec->spread;
+
+      cogl_material_set_color4ub (node->border_shadow_material,
+                                  paint_opacity, paint_opacity, paint_opacity, paint_opacity);
+
+      cogl_set_source (node->border_shadow_material);
+      cogl_rectangle_with_texture_coords (shadow_box.x1, shadow_box.y1, shadow_box.x2, shadow_box.y2,
+                                          0, 0, 1, 1);
+    }
+
   if (node->border_texture != COGL_INVALID_HANDLE)
     {
       /* Gradients and border images are mutually exclusive at this time */
@@ -1072,7 +1139,7 @@ st_theme_node_paint (StThemeNode           *node,
        * image (we could exend this in the future to take other CSS properties
        * like boder and background color into account).
        */
-      if (node->shadow_material != COGL_INVALID_HANDLE)
+      if (node->background_shadow_material != COGL_INVALID_HANDLE)
         {
           StShadow *shadow_spec;
           ClutterActorBox shadow_box;
@@ -1088,10 +1155,10 @@ st_theme_node_paint (StThemeNode           *node,
           shadow_box.y2 = background_box.y2 + shadow_spec->yoffset
                           + shadow_spec->blur + shadow_spec->spread;
 
-          cogl_material_set_color4ub (node->shadow_material,
+          cogl_material_set_color4ub (node->background_shadow_material,
                                       paint_opacity, paint_opacity, paint_opacity, paint_opacity);
 
-          cogl_set_source (node->shadow_material);
+          cogl_set_source (node->background_shadow_material);
           cogl_rectangle_with_texture_coords (shadow_box.x1, shadow_box.y1, shadow_box.x2, shadow_box.y2,
                                               0, 0, 1, 1);
         }
index 6074d5a0c80433abf80f33d53b16fabe1a66dc72..bd84ef7ae8a136ab6121f355f8c6238207442103 100644 (file)
@@ -64,7 +64,8 @@ struct _StThemeNode {
   float alloc_width;
   float alloc_height;
 
-  CoglHandle shadow_material;
+  CoglHandle background_shadow_material;
+  CoglHandle border_shadow_material;
   CoglHandle background_texture;
   CoglHandle border_texture;
   CoglHandle corner_texture;